package org.bookie.framework.services.impl;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.NestedMarkupWriter;
import org.apache.tapestry.markup.Attribute;

public class TextWriter implements IMarkupWriter {

	private OutputStream _outputStream;

	private PrintWriter _printWriter;

	private static final Log s_logger = LogFactory.getLog(TextWriter.class);

	public TextWriter(OutputStream outputStream, String encoding) {
		_outputStream = outputStream;
		if (encoding != null) {
			try {
				_printWriter = new PrintWriter(new OutputStreamWriter(
						_outputStream, encoding), true);
			} catch (UnsupportedEncodingException e) {
				s_logger.error("Encoding " + encoding + " not supported");
				_printWriter = new PrintWriter(_outputStream);
			}
		} else {
			_printWriter = new PrintWriter(_outputStream);
		}
	}

	public TextWriter(Writer writer) {
		_printWriter = new PrintWriter(writer);
	}

	public void attribute(String name, int value) {
		// do nothing
	}

	public void attribute(String name, boolean value) {
		// do nothing

	}

	public void attribute(String name, String value) {
		// do nothing
	}

	public void attributeRaw(String name, String value) {
		// do nothing
	}

	public void begin(String name) {
		// do nothing

	}

	public void beginEmpty(String name) {
		// do nothing
	}

	public boolean checkError() {
		return _printWriter.checkError();
	}

	public void close() {
		_printWriter.close();
	}

	public void closeTag() {
		// do nothing
	}

	public void comment(String value) {
		// do nothing
	}

	public void end() {
		// do nothing
	}

	public void end(String name) {
		// do nothing
	}

	public void flush() {
		_printWriter.flush();

	}

	public NestedMarkupWriter getNestedWriter() {
		return null;
	}

	public void print(char[] data, int offset, int length) {
		// _printWriter.write(data, offset, length);
		fixNewLine(data, offset, length);

	}

	public void print(char value) {
		_printWriter.print(value);

	}

	public void print(int value) {
		_printWriter.print(value);

	}

	public void fixNewLine(char[] buffer, int offset, int length) {
		boolean repl = false;
		String buf = new String(buffer, offset, length);
		if (buf.indexOf("\n") >= 0) {
			buf = buf.replaceAll("\n", "");
			repl = true;
		}
		if (buf.indexOf("\r") >= 0) {
			buf = buf.replaceAll("\r", "");
			repl = true;
		}
		if (buf.indexOf("<br>") >= 0) {
			buf = buf.replaceAll("<br>", "\n");
			repl = true;
		}
		if (repl)
			print(buf);
		else
			_printWriter.write(buffer, offset, length);

	}

	public final void fixNewLine2(char[] buffer, int offset, int length) {
		int rest = offset;
		for (int pos = offset; pos < length; pos++) {
			if (buffer[pos] == '\n' || buffer[pos] == '\r') {
				_printWriter.write(buffer, rest, pos - rest);
				rest = pos + 1;
			}
			if ((length - (pos - offset) >= 4) && buffer[pos] == '<'
					&& buffer[pos + 1] == 'b' && buffer[pos + 2] == 'r'
					&& buffer[pos + 3] == '>') {
				_printWriter.write(buffer, rest, pos - rest);
				_printWriter.print('\n');
				rest = pos + 4;
			}
		}
		int toWrite = length - (rest - offset);
		if (toWrite > 0)
			_printWriter.write(buffer, rest, toWrite);
	}

	public void print(String value) {
		_printWriter.print(value);

	}

	public void println() {
		// _printWriter.print("\n");
	}

	public void printRaw(char[] buffer, int offset, int length) {
		print(buffer, offset, length, true);
	}

	public void printRaw(String value) {
		print(value);

	}

	public String getContentType() {
		return "text/plain";
	}

	public void print(char[] data, int offset, int length, boolean raw) {
		print(data, offset, length);
	}

	public void print(String value, boolean raw) {
		print(value);
	}

	public void appendAttribute(String name, int value) {

	}

	public void appendAttribute(String name, boolean value) {

	}

	public void appendAttribute(String name, String value) {

	}

	public void appendAttributeRaw(String name, String value) {

	}

	public void clearAttributes() {

	}

	public Attribute getAttribute(String name) {
		return null;
	}

	public boolean hasAttribute(String name) {
		return false;
	}

	public Attribute removeAttribute(String name) {
		return null;
	}

}
